/**
 * LoadImageServlet.java
 */
using System;
using System.Web;

using Yawf.Core;
using Yawf.Core.Logs;
using Yawf.Core.Utils;

using Yawf.Web.Utils;
using Yawf.Web.HttpHandlers.Entities;
using Yawf.Core.Exceptions;

namespace Yawf.Web.HttpHandlers {
public class LoadBinaryDataController{
	private IBinaryDataLoader binaryLoader;

	// Properties
	public IBinaryDataLoader BinaryLoader { get{return binaryLoader;} set{binaryLoader = value;} }

	/// <summary>
	/// Here is were all the fun stuff happens. This method will handle a request
	/// for loading an image from source and return binarya data of image. Setting the
	/// corresponding content type this controller can be used to load images from database
	/// etc.
	/// </summary>
	/// <param name="context">HttpContext context object to use</param>
	public void ProcessRequest(HttpContext context) {
		ResponseWrapper responseWrapper;
		RequestWrapper requestWrapper;
		BinaryData tmpData = null;
		String fileName;
		
		try {
			if (BinaryLoader != null) {
				requestWrapper = new RequestWrapper(context.Request,context.Session);
				responseWrapper = new ResponseWrapper(context.Response);
				tmpData = BinaryLoader.LoadBinaryData(requestWrapper);
				
				if (tmpData != null && (tmpData.Data != null || tmpData.DataStream != null)) {
					// Set content type
					responseWrapper.Response.ContentType = tmpData.ContentType;
					responseWrapper.Response.AddHeader("Pragma","no-cache");
					responseWrapper.Response.AddHeader("Cache-Control", "no-cache");

					// Find file name
					fileName = GetFileName(requestWrapper, tmpData);
					if (!StringUtils.IsEmpty(fileName)) {
						responseWrapper.Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName);
					}

					// Write Binary Data to Response Output Stream					
					WriteBinarayData(responseWrapper.Response,tmpData);
					responseWrapper.Response.OutputStream.Flush();
				} else {
					responseWrapper.Response.StatusCode = 404; // SC_NOT_FOUND
				}
			}
		} catch(YawfException e) {
			Log.ExceptionMessage(this.GetType(), "Error al cargar binario,Root cause[" + e.Message + "]", e);
		} catch(Exception e) {
			Log.ExceptionMessage(this.GetType(),"Fatal Error when handling request ,Root cause[" + e.Message + "]",e);
		} finally {
			if (tmpData != null && tmpData.DataStream != null) {
				try { tmpData.DataStream.Close(); } catch (Exception e) { e.ToString();/* Do nothing, we are closing resource */};
			}
		}
	}

	/// <summary>
	/// Gets filename either from request or from the binaray data 
	/// </summary>
	/// <param name="wrapper">RequestWrapper to use to get from request</param>
	/// <param name="tmpData">Binary data to get filename from</param>
	/// <returns>A filename to use, from binaray first, if not defined from request</returns>
	private String GetFileName(RequestWrapper wrapper,BinaryData tmpData) {
		String fileName;

		fileName = tmpData.FileName;
		if (StringUtils.IsEmpty(fileName)) {
			fileName = wrapper.GetString("fileName", "");
		}
		return fileName;
	}

	/// <summary>
	/// Writes binaray data object to response output
	/// </summary>
	/// <param name="response">Http response to write binaray data</param>
	/// <param name="tmpData">the binaray data to write</param>
	private void WriteBinarayData(HttpResponse response,BinaryData tmpData){

		if (tmpData.DataStream != null) {
			ResourceUtils.CopyData(tmpData.DataStream, response.OutputStream);
		} else {
			response.OutputStream.Write(tmpData.Data,0,tmpData.Data.Length);
		}
	}
}
}